using Domain;
using ErrorCode;
using MediatR;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WriteAPI.Command.生产计划;

namespace WriteAPI.CommandHandle.生产计划
{
    /// <summary>
    /// 导出生产计划命令处理程序
    /// </summary>
    public class ExportProductionPlanCommandHandler : IRequestHandler<ExportProductionPlanCommand, APIResult<byte[]>>
    {
        private readonly ISqlSugarClient _db;

        public ExportProductionPlanCommandHandler(ISqlSugarClient db)
        {
            _db = db;
        }

        public async Task<APIResult<byte[]>> Handle(ExportProductionPlanCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<byte[]>();

            try
            {
                // 构建查询
                var query = _db.Queryable<Lwp_ProductionPlan>()
                    .WhereIF(request.PlanIds != null && request.PlanIds.Any(), p => request.PlanIds.Contains(p.Id))
                    .WhereIF(!string.IsNullOrEmpty(request.Keyword), p => 
                        p.DocNumber.Contains(request.Keyword) || 
                        p.VersionDesc.Contains(request.Keyword))
                    .WhereIF(request.StartDate.HasValue, p => p.DocDate >= request.StartDate.Value)
                    .WhereIF(request.EndDate.HasValue, p => p.DocDate <= request.EndDate.Value)
                    .OrderByDescending(p => p.Id);

                // 获取数据
                var plans = await query.ToListAsync();
                var planIds = plans.Select(p => p.Id).ToList();

                // 获取明细数据
                var details = await _db.Queryable<ProductionPlanDetail>()
                    .Where(d => planIds.Contains(d.PlanId))
                    .ToListAsync();

                // 根据导出类型选择不同的导出方式
                if (request.ExportType.Equals("CSV", StringComparison.OrdinalIgnoreCase))
                {
                    // 使用CSV格式导出
                    result.Data = ExportToCSV(plans, details);
                }
                else
                {
                    // 默认使用简单文本格式导出
                    result.Data = ExportToTextFormat(plans, details);
                }

                result.Success = true;
                result.Code = 200;
                result.Message = "导出成功";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.Code = 500;
                result.Message = $"导出生产计划失败: {ex.Message}";
            }

            return result;
        }

        /// <summary>
        /// 导出为CSV格式
        /// </summary>
        private byte[] ExportToCSV(List<Lwp_ProductionPlan> plans, List<ProductionPlanDetail> details)
        {
            var sb = new StringBuilder();
            
            // 添加CSV表头
            sb.AppendLine("序号,计划编号,计划主题,单据日期,物品描述,物品数量,关联项目,销售订单,备注");
            
            // 添加数据行
            for (int i = 0; i < plans.Count; i++)
            {
                var plan = plans[i];
                var planDetails = details.Where(d => d.PlanId == plan.Id).ToList();
                var itemCount = planDetails.Count;

                var itemDesc = itemCount > 0
                    ? string.Join(" ", planDetails.Select(d => d.ItemName).Take(3))
                    : "无物品";
                if (itemCount > 3) itemDesc += "...";
                
                // 在CSV中需要处理特殊字符，例如逗号和引号
                itemDesc = itemDesc.Replace("\"", "\"\""); // 将引号替换为两个引号（CSV标准）
                if (itemDesc.Contains(",")) itemDesc = $"\"{itemDesc}\""; // 如果包含逗号，用引号包围整个字段
                
                var planTheme = plan.VersionDesc?.Replace("\"", "\"\"") ?? "";
                if (planTheme.Contains(",")) planTheme = $"\"{planTheme}\"";
                
                var remark = plan.Remark?.Replace("\"", "\"\"") ?? "";
                if (remark.Contains(",")) remark = $"\"{remark}\"";

                sb.AppendLine($"{i + 1},{plan.DocNumber},{planTheme},{plan.DocDate:yyyy-MM-dd},{itemDesc},{itemCount},{plan.BizUser},{plan.BizNumber},{remark}");
            }
            
            return Encoding.UTF8.GetBytes(sb.ToString());
        }

        /// <summary>
        /// 导出为简单文本格式
        /// </summary>
        private byte[] ExportToTextFormat(List<Lwp_ProductionPlan> plans, List<ProductionPlanDetail> details)
        {
            var sb = new StringBuilder();
            
            // 添加表头
            sb.AppendLine("生产计划导出报表");
            sb.AppendLine("导出时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            sb.AppendLine("------------------------------------------------------------");
            sb.AppendLine("序号\t计划编号\t计划主题\t单据日期\t物品描述\t物品数量\t关联项目\t销售订单\t备注");
            sb.AppendLine("------------------------------------------------------------");
            
            // 添加数据行
            for (int i = 0; i < plans.Count; i++)
            {
                var plan = plans[i];
                var planDetails = details.Where(d => d.PlanId == plan.Id).ToList();
                var itemCount = planDetails.Count;

                var itemDesc = itemCount > 0
                    ? string.Join(" ", planDetails.Select(d => d.ItemName).Take(3))
                    : "无物品";
                if (itemCount > 3) itemDesc += "...";
                
                sb.AppendLine($"{i + 1}\t{plan.DocNumber}\t{plan.VersionDesc}\t{plan.DocDate:yyyy-MM-dd}\t{itemDesc}\t{itemCount}\t{plan.BizUser}\t{plan.BizNumber}\t{plan.Remark}");
            }
            
            sb.AppendLine("------------------------------------------------------------");
            sb.AppendLine($"总记录数：{plans.Count}");
            
            return Encoding.UTF8.GetBytes(sb.ToString());
        }
    }
} 